/*
 *  Tool.c
 *  
 *
 *  Created by xia on 11-1-24.
 *  Copyright 2011 __MyThlink__. All rights reserved.
 *	// 夏炳献
 */

#include "Tool.h"

#include "string.h"
#include "stdlib.h"
#include "time.h"
#include "stdio.h"

#include "rsa.h"
#include "rsaeuro.h"


#define PUBE "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001"


#pragma mark========

// RSA 加密函数［私有］
int enc(char *pube,char *pubm,char *inbuf,int inlen,char *outbuf,int *outlen);
int PKEncDESKey(char *PubKey,char *DESKey,char *PEBuffer);
void ASCII_to_Hex( char *hex_buf, char *asc_buf, int len );
void Hex_to_ASCII( char *asc_buf, char *hex_buf, int len );
void initPub(R_RSA_PUBLIC_KEY *rsapub,char *pube,char *pubm);

#pragma mark========

void initPub(R_RSA_PUBLIC_KEY *rsapub,char *pube,char *pubm)
{
	char buf[2048];
	char hbuf[1024];
	strcpy(buf,"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001");
	//	strcpy(buf,pube);
	ASCII_to_Hex(hbuf,buf,256);
	rsapub->bits = 1024;
	memcpy(rsapub->exponent,hbuf,128);
	//strcpy(buf,"6DDAA409C3F941BDF45897201A915C4FE93DAB23158A920D4C641B4E3FC0331570FEB9BEB83BF6FE27D024953FF90EB51AF68CFC1BA18C8C20968CA9B6069A4206137A414F724F5F051B1A15D36EDFFFAD5CB0A959B14EDB2EDADEA189049D34DD9A33E1B586F5F94761CD0EFF377CE1E4A415F3CBCA16E8B75BCE78FBF07701");
	strcpy(buf,pubm);
	ASCII_to_Hex(hbuf,buf,256);
	memcpy(rsapub->modulus,hbuf,128);
}

int enc(char *pube,char *pubm,char *inbuf,int inlen,char *outbuf,int *outlen)
{
	R_RSA_PUBLIC_KEY rsapub;
	
	unsigned char output[2048];         
	unsigned int  outputLen;        
	
	initPub(&rsapub,pube,pubm);
	memset(output,0,sizeof(output));
	
	RSAPublicEnc(output, &outputLen, (unsigned char*)inbuf, inlen, &rsapub);
	Hex_to_ASCII(outbuf,(char*)output,2*outputLen);
	*outlen = 2*outputLen;
    return 0;
	
}

#pragma mark

int PKEncDESKey(char *PubKey,char *DESKey,char *PEBuffer)
{
	char pube[516];
	char pubm[2048];
	char outbuf[516];
	char DKbuf[1025];
	char PBKbuf[516];
	char tmpbuf[516];
	char mypin[1025],buf[10];
	char PBKBuffer1[1025];
	int outlen = 0;
	int pinlen,rnd;
	//	int i;
	
	memset(mypin,0,sizeof(mypin));
	
	pinlen = strlen(DESKey);
	
	Hex_to_ASCII(mypin,DESKey,pinlen*2);
	
	memset(pubm,0,sizeof(pubm));
	strcpy(pubm,PubKey);
	memset(DKbuf,0,sizeof(DKbuf));
	strcpy(DKbuf,mypin);
	
	//gen random data
	
	memset(pube,0,sizeof(pube));
	
	outlen=strlen(DKbuf);
	srand( (unsigned)time( NULL ) ); 
	
    for(;;) 
    { 
		rnd = rand(); 
		memset(buf,0,sizeof(buf));
		//sprintf(buf,"%02X",255);
		sprintf(buf,"%04X",rnd);
		strcat(DKbuf,buf);
		
		if(strlen(DKbuf)>=256)
			break;
    } 
    DKbuf[256]=0;
	
	strcpy(pube,PUBE);
	
	memset(outbuf,0,sizeof(outbuf));
	
	memset(PBKbuf,0,sizeof(PBKbuf));
	
	strcpy(PBKbuf,DKbuf);//,pinlen*2+2);
	memset(tmpbuf,0,sizeof(tmpbuf));
	
	memset(PBKBuffer1,0,sizeof(PBKBuffer1));
	strcpy(PBKBuffer1,PBKbuf);
	ASCII_to_Hex((char*)PBKBuffer1,PBKbuf,strlen(PBKbuf));
	
	enc(pube,pubm,PBKBuffer1,strlen(PBKbuf)/2,outbuf,&outlen);
	
	strcpy(PEBuffer,outbuf);
	
	return 0;
}

#pragma mark

void ASCII_to_Hex( char *hex_buf, char *asc_buf, int len )
{
	int	i,leng;
	char	ch;
	
	leng = len / 2;
	for( i=0; i<leng; i++ )
	{
		ch = asc_buf[2*i];
		if ( ch >= '0' && ch <= '9' )
			ch = ch - '0';
		else
			if ( ch >= 'a' && ch <= 'f' )
				ch = ch - 'a' + 0x0a;
			else
				if ( ch >= 'A' && ch <= 'F' )
					ch = ch - 'A' + 0x0a;
				else
					ch = 0x00;
		hex_buf[i] = ch << 4; 
		ch = asc_buf[2*i+1];
		if ( ch >= '0' && ch <= '9' )
			ch = ch - '0';
		else
			if ( ch >= 'a' && ch <= 'f' )
				ch = ch - 'a' + 0x0a;
			else
				if ( ch >= 'A' && ch <= 'F' )
					ch = ch - 'A' + 0x0a;
				else
					ch = 0x00;
		hex_buf[i] = hex_buf[i] + ch; 
	}
}

#pragma mark

void Hex_to_ASCII( char *asc_buf, char *hex_buf, int len )
{
	int	i;
	char	ch;
	
	for( i=0; i<len; i+=2 )
	{
		ch = ( hex_buf[i/2] & 0xf0 ) >> 4;
		if ( ch >= 0x0a && ch <= 0x0f )
			asc_buf[i] = ch + 'A' - 10;
		else
			asc_buf[i] = ch +'0';
		ch =  hex_buf[i/2] & 0x0f ;
		if ( ch >= 0x0a && ch <= 0x0f )
			asc_buf[i+1] = ch + 'A' - 10;
		else
			asc_buf[i+1] = ch +'0';
	}
}


#pragma mark=================
/*
 RSA加密函数［用于密码的加密］
 @char* encodeData：需要加密的串
 @char* encodeKey：密钥 
 @char *outBuf：加密返回的串 
 */
int RSAEncodeData(char* encodeData, char* encodeKey,char *outBuf)
{
	char PINbuf[32];				// 用户PIN
	char PKbuf[2048];				// 公钥
	char PKEbuf[2048];				// 公钥加密后的密文
	char EncData[2096];				// 返回的报文
	
# if TOOL_OUT_DATA_FLAG
	printf("Encode Per Data;%s\n",encodeData);
#endif
	 
	// strcspn[越界？]
	strcpy(PINbuf,encodeData);
	memset(PINbuf,0,sizeof(PINbuf));
	PINbuf[0]='0'+strlen(encodeData)/10;
	PINbuf[1]='0'+strlen(encodeData)%10;
	memcpy(PINbuf+2,encodeData,strlen(encodeData));
	
	//公钥
	memset(PKbuf,0,sizeof(PKbuf));
	memcpy(PKbuf,encodeKey,strlen(encodeKey));
	
	
	memset(PKEbuf,0,sizeof(PKEbuf));
	
	PKEncDESKey(PKbuf,PINbuf,PKEbuf);
	
	memset(EncData,0,sizeof(EncData));
	memcpy(EncData,PKEbuf,256);
	
	strcpy(outBuf,EncData);
	
# if TOOL_OUT_DATA_FLAG
	printf("Encode Aft Data;%s\n",outBuf);
#endif
	
	return 0;	
}